from src.mqtt import Mqtt
from src.ledController import LEDController
from src.yamlLoader import YamlLoader
from src.log import Log
from src.log import log
from src.snowboy.snowboy import Snowboy
from src.snowboy.snowboyController import snowboy_callback
import os
import sys
import signal
import time

# 将项目根目录添加到 sys.path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

def initialize_modules(config, log):
    log.info("初始化 LED 控制器...")
    led = LEDController(pin=config['led']['pin'], config=config)
    log.info("LED 控制器初始化成功")

    log.info("启动 MQTT 客户端...")
    userdata = {'led': led}
    mqtt = Mqtt(userdata=userdata,broker=config['mqtt']['broker'],
                port=config['mqtt']['port'],
                client_id=config['mqtt']['client_id'],
                username=config['mqtt']['username'],
                password=config['mqtt']['password'])
    log.info("MQTT 客户端启动成功")
    
    log.info("启动 Snowboy 语音唤醒...")
    snowboy = Snowboy(model=config['snowboy']['model'],
                      sensitivity=config['snowboy']['sensitivity'],
                      audio_gain=config['snowboy']['audio_gain'])
    snowboy.set_detected_callback(lambda: snowboy_callback(log=log, mqtt=mqtt, led=led, config=config))
    snowboy.start()
    log.info("Snowboy 启动成功")

    log.info("订阅 LED 主题...")
    mqtt.subscribe(config['topic']['led'])
    log.info("LED 主题订阅成功")

    return led, snowboy, mqtt

def signal_handler(sig, frame):
    log.info("收到终止信号，准备退出...")
    if snowboy:
        snowboy.stop()
    if mqtt:
        mqtt.loop_stop()
    sys.exit(0)


if __name__ == '__main__':    
    signal.signal(signal.SIGINT, signal_handler)  # 捕获 Ctrl+C
    signal.signal(signal.SIGTERM, signal_handler)  # 捕获终止信号
    mqtt = None
    snowboy = None
    try:
        yaml_loader = YamlLoader()
        config = yaml_loader.get_config()
        led, snowboy, mqtt = initialize_modules(config, log)
        mqtt.loop_start()

        try:
            while True:
                time.sleep(1)  # 减少 CPU 占用
        except Exception as e:
            log.error("主循环出错: {}".format(e))
    except Exception as e:
        log.error("程序初始化出错: {}".format(e))
    finally:
        if snowboy:
            snowboy.stop()
        if mqtt:
            mqtt.loop_stop()
        log.info("资源已释放，程序退出")